package com.stable.web.controller;

import com.stable.service.HorizontalService;
import com.stable.utils.DateUtil;
import com.stable.utils.FileUtil;
import com.stable.vo.bus.HorizontalInfo;
import com.stable.vo.http.JsonResult;
import com.stable.vo.spi.req.EsQueryPageReq;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 水平运行分析
 */
@RequestMapping("/horizontal")
@RestController
@Log4j2
public class HorizontalController {

    @Autowired
    private HorizontalService horizontalService;


    /**
     * 水平涨跌幅度最近7日统计
     *
     * @param forceJob                  强制重新执行job，重新计算写入redis数据
     * @param startDate                 日线数据过滤开始时间
     * @param endDate                   日线数据过滤结束时间
     * @param code                      单个股票代码，方便测试
     * @param startStepDays             开始阶段的天数                                 85天
     * @param startStepFullLimitCount   开始阶段涨停数，如果小于则不满足直接排除         1个涨停板
     * @param startStepRange            开始阶段的涨幅，如果小于则不满足直接排除         50%涨幅
     * @param calculateAvgCountN        水平阶段 计算平均数的N天值                      10天的平均值
     * @param avgNDownRange             水平阶段 计算跌幅范围                           水平阶段的平均价 与 10天平均值的跌幅
     * @param avgNDownRMoreExcludeCount 水平阶段 计算跌幅范围超过数量后，则直接删除       跌幅数量超过N 则剔除
     * @param avgNUpRange               水平阶段 计算涨幅范围                           水平阶段的平均价 与 10天平均值的涨幅
     * @param avgNUpRMoreExcludeCount   水平阶段 计算涨幅范围超过数量后，则直接删除       涨幅数量超过N 则剔除
     * @param moreThanMa250Range        水平阶段 250日线上的天数比例                     80%
     * @param near7daysRange            计算最近7个交易日的接近涨跌幅范围的天数           10%
     * @param conceptName               概念关机键
     * @param topToNDownRange           开始阶段最高价与水平阶段的最低价范围不能小于       <35%
     * @return
     */
    @RequestMapping(value = "/horizontalRange", method = RequestMethod.GET)
    public ResponseEntity<JsonResult> stocklist(@RequestParam(name = "forceJob", defaultValue = "false", required = false) Boolean forceJob,
                                                String queryDate,
                                                String startDate,
                                                String endDate,
                                                String code,
                                                @RequestParam(name = "startStepDays", defaultValue = "85", required = false) int startStepDays,
                                                @RequestParam(name = "startStepFullLimitCount", defaultValue = "1", required = false) int startStepFullLimitCount,
                                                @RequestParam(name = "startStepRange", defaultValue = "50", required = false) int startStepRange,
                                                @RequestParam(name = "calculateAvgCountN", defaultValue = "10", required = false) int calculateAvgCountN,
                                                @RequestParam(name = "avgNDownRange", defaultValue = "-15", required = false) int avgNDownRange,
                                                @RequestParam(name = "avgNDownRMoreExcludeCount", defaultValue = "2", required = false) int avgNDownRMoreExcludeCount,
                                                @RequestParam(name = "avgNUpRange", defaultValue = "15", required = false) int avgNUpRange,
                                                @RequestParam(name = "avgNUpRMoreExcludeCount", defaultValue = "10", required = false) int avgNUpRMoreExcludeCount,
                                                @RequestParam(name = "moreThanMa250Range", defaultValue = "80", required = false) int moreThanMa250Range,
                                                @RequestParam(name = "near7daysRange", defaultValue = "10", required = false) int near7daysRange,
                                                @RequestParam(name = "sortBy250", defaultValue = "true", required = false) Boolean sortBy250,
                                                @RequestParam(name = "conceptName", defaultValue = "", required = false) String conceptName,
                                                @RequestParam(name = "topToNDownRange", defaultValue = "35", required = false) int topToNDownRange,
                                                EsQueryPageReq queryPage) {
        log.info("forceJob:{},queryDate:{},startDate:{},endDate:{},code:{},startStepDays:{},startStepFullLimitCount:{},startStepRange:{},calculateAvgCountN:{},avgNDownRange:{},avgNDownRMoreExcludeCount:{}, avgNUpRange:{},avgNUpRMoreExcludeCount:{},moreThanMa250Range:{},near7daysRange:{},sortBy250:{},topToNDownRange:{}", forceJob, queryDate, startDate, endDate, code, startStepDays, startStepFullLimitCount, startStepRange, calculateAvgCountN, avgNDownRange, avgNDownRMoreExcludeCount, avgNUpRange, avgNUpRMoreExcludeCount, moreThanMa250Range, near7daysRange, sortBy250, topToNDownRange);
        queryPage.setPageSize(1000);
        if (StringUtils.isEmpty(queryPage.getSortName())) {
            queryPage.setSortName("tradeDate");
        }
        if (StringUtils.isEmpty(queryDate)) queryDate = DateUtil.getTodayYYYYMMDD();
        JsonResult r = new JsonResult();
        try {
            r.setResult(horizontalService.queryHorizontal(forceJob, queryDate, startDate, endDate, code, queryPage, startStepDays, startStepFullLimitCount, startStepRange, calculateAvgCountN, avgNDownRange, avgNDownRMoreExcludeCount, avgNUpRange, avgNUpRMoreExcludeCount, moreThanMa250Range, near7daysRange, sortBy250, conceptName, topToNDownRange));
            r.setStatus(JsonResult.OK);
        } catch (Exception e) {
            r.setResult(e.getClass().getName() + ":" + e.getMessage());
            r.setStatus(JsonResult.ERROR);
            e.printStackTrace();
        }
        return ResponseEntity.ok(r);
    }


    /**
     * 下载文件
     *
     * @return
     */
    @RequestMapping({"/download"})
    public void download(@RequestParam(name = "forceJob", defaultValue = "false", required = false) Boolean forceJob,
                         String queryDate,
                         String startDate,
                         String endDate,
                         String code,
                         @RequestParam(name = "startStepDays", defaultValue = "85", required = false) int startStepDays,
                         @RequestParam(name = "startStepFullLimitCount", defaultValue = "1", required = false) int startStepFullLimitCount,
                         @RequestParam(name = "startStepRange", defaultValue = "50", required = false) int startStepRange,
                         @RequestParam(name = "calculateAvgCountN", defaultValue = "10", required = false) int calculateAvgCountN,
                         @RequestParam(name = "avgNDownRange", defaultValue = "-15", required = false) int avgNDownRange,
                         @RequestParam(name = "avgNDownRMoreExcludeCount", defaultValue = "2", required = false) int avgNDownRMoreExcludeCount,
                         @RequestParam(name = "avgNUpRange", defaultValue = "15", required = false) int avgNUpRange,
                         @RequestParam(name = "avgNUpRMoreExcludeCount", defaultValue = "10", required = false) int avgNUpRMoreExcludeCount,
                         @RequestParam(name = "moreThanMa250Range", defaultValue = "80", required = false) int moreThanMa250Range,
                         @RequestParam(name = "near7daysRange", defaultValue = "10", required = false) int near7daysRange,
                         @RequestParam(name = "sortBy250", defaultValue = "true", required = false) Boolean sortBy250,
                         @RequestParam(name = "conceptName", defaultValue = "", required = false) String conceptName,
                         @RequestParam(name = "topToNDownRange", defaultValue = "35", required = false) int topToNDownRange,
                         EsQueryPageReq queryPage) {
        queryPage.setPageSize(1000);
        if (StringUtils.isEmpty(queryPage.getSortName())) {
            queryPage.setSortName("tradeDate");
        }
        if (StringUtils.isEmpty(queryDate)) queryDate = DateUtil.getTodayYYYYMMDD();
        List<HorizontalInfo> horizontalInfos = horizontalService.queryHorizontal(forceJob, queryDate, startDate, endDate, code, queryPage, startStepDays, startStepFullLimitCount, startStepRange, calculateAvgCountN, avgNDownRange, avgNDownRMoreExcludeCount, avgNUpRange, avgNUpRMoreExcludeCount, moreThanMa250Range, near7daysRange, sortBy250, conceptName, topToNDownRange);

        String filename = "水平运行分析列表.txt";
        FileUtil.downloadFile(horizontalInfos.stream().map(HorizontalInfo::getCode).collect(Collectors.toList()), filename);
    }
}
